﻿#region

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
using System.Web.Mvc;
using CuongHanh.Models;
using Ext.Net;
using Ext.Net.MVC;
using Newtonsoft.Json;
using Icon = Ext.Net.Icon;
using Image = System.Drawing.Image;
using JsonSerializer = CuongHanh.Context.JsonSerializer;
using JsonWriter = Newtonsoft.Json.JsonWriter;

#endregion

namespace CuongHanh.Controllers.BO
{
    public class ABaseController : Controller
    {
        protected int GetUserId()
        {
            if(Session[AppUtil.USER_ID] != null)
                return (int) Session[AppUtil.USER_ID];
            return 0;
        }

        protected string GetLanguage()
        {
            return Session[AppUtil.LANGUAGE] != null
                    ? string.Format("{0}",
                            Session[AppUtil.LANGUAGE])
                    : AppUtil.LANGUAGE_VI;
        }

        protected void ShowWindow(string id,
                bool show)
        {
            if(show)
                this.GetCmp<Window>(id).Show();
            else
                this.GetCmp<Window>(id).Hide();
        }

        protected void ShowWindow(string id,
                bool show,
                int width,
                int height)
        {
            if(show)
            {
                Window cWindow = this.GetCmp<Window>(id);
                cWindow.SetHeight(height);
                cWindow.SetWidth(width);
                cWindow.Show();
            }
            else
                this.GetCmp<Window>(id).Hide();
        }

        protected void ReloadStore(string id)
        {
            this.GetCmp<Store>(id).LoadProxy();
        }

        protected void ResetForm(string formName)
        {
            this.GetCmp<FormPanel>(formName).Reset();
        }

        protected ActionResult ShowWindow<T>(string viewName,
                string containerId,
                T model)
        {
            ShowWindow(containerId,
                    true);
            return this.PartialExtView(
                                       viewName: viewName,
                    containerId: containerId,
                    model: model,
                    mode: RenderMode.AddTo,
                    clearContainer: true
                    );
        }

        protected ActionResult ShowWindow<T>(string viewName,
                string containerId,
                T model,
                int? width,
                int? height)
        {
            if(height.HasValue
               && width.HasValue)
                ShowWindow(containerId,
                        true,
                        width.Value,
                        height.Value);
            else
                ShowWindow(containerId,
                        true);
            return this.PartialExtView(
                                       viewName: viewName,
                    containerId: containerId,
                    model: model,
                    mode: RenderMode.AddTo,
                    clearContainer: true
                    );
        }

        protected void ShowNotification(UpdateResult result)
        {
            X.Msg.Notify(new NotificationConfig
                         {
                                 Icon = result.State == 4
                                         ? Icon.Error
                                         : Icon.Accept,
                                 Title = "Message",
                                 Html = string.Format("{0}",
                                         result.Value)
                         }).Show();
        }

        public string GetControllerByBranch(int branchId)
        {
            return branchId == AppUtil.GEM_CODE
                    ? "Gem"
                    : branchId == AppUtil.WOOD_CODE
                            ? "Wood"
                            : "Stone";
        }

        public string GetBranchName(int branchId)
        {
            return branchId == AppUtil.GEM_CODE
                    ? AppUtil.GEM_NAME
                    : branchId == AppUtil.WOOD_CODE
                            ? AppUtil.WOOD_NAME
                            : AppUtil.STONE_NAME;
        }

        public string ChangeBannerImage(Banner model,
                byte[] datas,
                Stream stream)
        {
            string imgType = GetImageMimeType(datas);
            string bannerPath = AppUtil.GetBannerPath(model.BranchId);

            #region LagreImage

            string curPath = Server.MapPath(bannerPath);
            if(!Directory.Exists(curPath))
                Directory.CreateDirectory(curPath);
            string large = string.Format("{0}\\{1}",
                    curPath,
                    model.Image);

            System.IO.File.WriteAllBytes(large,
                    datas);

            #endregion

            ResizeAndWrite(stream,
                    curPath,
                    model.Image,
                    imgType,
                    AppUtil.HEIGHT_THUMNAIL);
            return model.Image;
        }

        public string WriteByteToFileForGem(byte[] datas,
                Stream stream)
        {
            try
            {
                string imgType = GetImageMimeType(datas);
                string time = DateTime.Now.ToString(AppUtil.DATE_TIME_FORMAT3);
                string fileName = string.Format("{0}.{1}",
                        time,
                        imgType);

                #region LagreImage

                string curPath = Server.MapPath(AppUtil.GEM_IMAGE_PATH);
                if(!Directory.Exists(curPath))
                    Directory.CreateDirectory(curPath);
                string large = string.Format("{0}\\{1}",
                        curPath,
                        fileName);

                System.IO.File.WriteAllBytes(large,
                        datas);

                #endregion

                return fileName;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            return string.Empty;
        }

        #region Images

        public string GetImageMimeType(byte[] imageData)
        {
            String mimeType = "image/unknown";

            try
            {
                Guid id;

                using (MemoryStream ms = new MemoryStream(imageData))
                {
                    using (Image img = Image.FromStream(ms))
                    {
                        id = img.RawFormat.Guid;
                    }
                }

                if(id == ImageFormat.Png.Guid)
                {
                    mimeType = "png";
                }
                else if(id == ImageFormat.Bmp.Guid)
                {
                    mimeType = "bmp";
                }
                else if(id == ImageFormat.Emf.Guid)
                {
                    mimeType = "x-emf";
                }
                else if(id == ImageFormat.Exif.Guid)
                {
                    mimeType = "jpeg";
                }
                else if(id == ImageFormat.Gif.Guid)
                {
                    mimeType = "gif";
                }
                else if(id == ImageFormat.Icon.Guid)
                {
                    mimeType = "ico";
                }
                else if(id == ImageFormat.Jpeg.Guid)
                {
                    mimeType = "jpeg";
                }
                else if(id == ImageFormat.MemoryBmp.Guid)
                {
                    mimeType = "bmp";
                }
                else if(id == ImageFormat.Tiff.Guid)
                {
                    mimeType = "tiff";
                }
                else if(id == ImageFormat.Wmf.Guid)
                {
                    mimeType = "wmf";
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            return mimeType;
        }

        public ImageFormat GetImageFormat(string type)
        {
            switch (type)
            {
                case "png":
                    return ImageFormat.Png;
                case "bmp":
                    return ImageFormat.Bmp;
                case "x-emf":
                    return ImageFormat.Emf;
                case "jpg":
                    return ImageFormat.Jpeg;
                case "ico":
                    return ImageFormat.Icon;
                case "tiff":
                    return ImageFormat.Tiff;
            }
            return ImageFormat.Jpeg;
        }

        public string WriteByteToFile(byte[] datas,
                Stream stream)
        {
            try
            {
                string imgType = GetImageMimeType(datas);
                string time = DateTime.Now.ToString(AppUtil.DATE_TIME_FORMAT3);
                string fileName = string.Format("{0}.{1}",
                        time,
                        imgType);

                #region LagreImage

                string curPath = Server.MapPath(AppUtil.LARGE_IMAGE_PATH);
                if(!Directory.Exists(curPath))
                    Directory.CreateDirectory(curPath);
                string large = string.Format("{0}\\{1}",
                        curPath,
                        fileName);

                System.IO.File.WriteAllBytes(large,
                        datas);

                #endregion

                ResizeAndWrite(stream,
                        AppUtil.SMALL_IMAGE_PATH,
                        fileName,
                        imgType,
                        AppUtil.HEIGHT_SMALL);
                ResizeAndWrite(stream,
                        AppUtil.THUMNAIL_IMAGE_PATH,
                        fileName,
                        imgType,
                        AppUtil.HEIGHT_THUMNAIL);

                return fileName;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }
            return string.Empty;
        }

        public void SaveByteArrayToImageByHeight(Stream stream,
                string path,
                string fileName,
                string imgType,
                int imageHeight)
        {
            Image image = Image.FromStream(stream);
            string curPath = Server.MapPath(path);
            if(!Directory.Exists(curPath))
                Directory.CreateDirectory(curPath);
            string fullPath = string.Format("{0}\\{1}",
                    curPath,
                    fileName);
            MemoryStream memoryStream = new MemoryStream();
            (new Bitmap(image,
                    new Size((image.Width * imageHeight / image.Height),
                            imageHeight))).Save(memoryStream,
                                    GetImageFormat(imgType));
            System.IO.File.WriteAllBytes(fullPath,
                    memoryStream.GetBuffer());
        }

        public void DeleteAllThisFile(string fileName)
        {
            DeleteFile(string.Format("{0}\\{1}",
                    Server.MapPath(AppUtil.LARGE_IMAGE_PATH),
                    fileName));
            DeleteFile(string.Format("{0}\\{1}",
                    Server.MapPath(AppUtil.SMALL_IMAGE_PATH),
                    fileName));
            DeleteFile(string.Format("{0}\\{1}",
                    Server.MapPath(AppUtil.THUMNAIL_IMAGE_PATH),
                    fileName));
        }

        public void DeleteFile(string fullPath)
        {
            if(System.IO.File.Exists(fullPath))
                System.IO.File.Delete(fullPath);
        }

        public byte[] GetByteArrayFromImage(string fileName,
                string path)
        {
            string fullPath = string.Format("{0}\\{1}",
                    Server.MapPath(path),
                    fileName);
            if(System.IO.File.Exists(fullPath))
            {
                Image image = Image.FromFile(fullPath);
                MemoryStream memoryStream = new MemoryStream();
                image.Save(memoryStream,
                        GetImageFormat(fileName.Split('.')[1]));
                return memoryStream.GetBuffer();
            }
            return null;
        }

        public ActionResult GetImage(string fileName,
                string path)
        {
            byte[] bytes = GetByteArrayFromImage(fileName,
                    path);
            if(bytes != null)
                return File(bytes,
                        "image/jpeg");
            return null;
        }

        public MemoryStream Resize(Image img,
                int newWidth,
                int newHeight)
        {
            Bitmap bmp = new Bitmap(img,
                    newWidth,
                    newHeight);
            using (Graphics g = Graphics.FromImage(bmp))
            {
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.SmoothingMode = SmoothingMode.HighQuality;
                g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                g.CompositingQuality = CompositingQuality.HighQuality;
                using (ImageAttributes wrapMode = new ImageAttributes())
                {
                    wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                    Rectangle destRect = new Rectangle(0,
                            0,
                            newWidth,
                            newHeight);
                    g.DrawImage(img,
                            destRect,
                            0,
                            0,
                            img.Width,
                            img.Height,
                            GraphicsUnit.Pixel,
                            wrapMode);
                }
            }
            MemoryStream memoryStream = new MemoryStream();
            bmp.Save(memoryStream,
                    GetImageFormat("jpg"));
            return memoryStream;
        }

        public void ResizeAndWrite(Stream stream,
                string path,
                string fileName,
                string imgType,
                int imageHeight)
        {
            Image image = Image.FromStream(stream);
            string curPath = Server.MapPath(path);
            if(!Directory.Exists(curPath))
                Directory.CreateDirectory(curPath);
            string fullPath = string.Format("{0}\\{1}",
                    curPath,
                    fileName);

            System.IO.File.WriteAllBytes(fullPath,
                    Resize(image,
                            imageHeight,
                            imageHeight).GetBuffer());
        }

        #endregion

        #region Article Image

        public bool WriteFileFromString64(string fileName,
                string image)
        {
            try
            {
                int index = image.IndexOf(',');
                image = image.Substring(index + 1,
                        image.Length - index - 1);
                string path = Server.MapPath(AppUtil.ARTICLE_IMAGE);
                if(!Directory.Exists(path))
                    Directory.CreateDirectory(path);
                byte[] bytes = Convert.FromBase64String(image);
                using (FileStream imageFile = new FileStream(string.Format("{0}{1}",
                        path,
                        fileName),
                        FileMode.Create))
                {
                    imageFile.Write(bytes,
                            0,
                            bytes.Length);
                    imageFile.Flush();
                }
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }

        #endregion

        #region function

        protected string FormatResult<T>(int total,
                IEnumerable<T> list)
        {
            StringBuilder stringBuilder = new StringBuilder();
            JsonWriter writer = new JsonTextWriter(new StringWriter(stringBuilder));
            writer.Formatting = Formatting.None;
            writer.WriteStartObject();
            writer.WritePropertyName("total");
            writer.WriteValue(total);
            writer.WritePropertyName("data");
            writer.WriteValue(JsonSerializer.SerializeList(list));
            writer.WriteEndObject();
            return stringBuilder.ToString();
        }

        #endregion
    }
}
